package bigapps.myneighbor.util;

import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLEncoder;

import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathFactory;

import org.apache.commons.csv.CSVParser;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;

import bigapps.myneighbor.exception.MyNeighborException;


public class LatitudeLongitudeUtil {
	public static double[] getLatitudeLongitude(String address) throws Exception
	{
		/*
		System.out.println("http://rpc.geocoder.us/service/csv?address=" + URLEncoder.encode(address, "UTF-8"));
		URL url = new URL("http://rpc.geocoder.us/service/csv?address=" + URLEncoder.encode(address, "UTF-8"));
		float result[] = new float[2];
		InputStream is = url.openStream();
		BufferedReader reader = new BufferedReader(new InputStreamReader(is));
//		System.out.println(reader.readLine());

		CSVParser parser = new CSVParser(reader);
		String line[] = null;
		line = parser.getLine();
		
		if(line != null)
		{
			result[0] = Float.valueOf(line[0]);
			result[1] = Float.valueOf(line[1]);
			return result;
		}
		else
		{
			return null;
		}
		*/
		/* using Google MAP API */
//		System.out.println("http://maps.google.com/maps/api/geocode/xml?address=" + URLEncoder.encode(address, "UTF-8"));
		String urlStr = "http://maps.google.com/maps/api/geocode/xml?address=" + URLEncoder.encode(address, "UTF-8") + "&sensor=false";
		URL url = new URL(urlStr);

		StringBuffer buffer = new StringBuffer();
		String response = null;
		double result[] = new double[2];
		InputStream is = url.openStream();
		BufferedInputStream bis = new BufferedInputStream(is);
		ByteArrayOutputStream aos = new ByteArrayOutputStream();
		
		byte b[] = new byte[10000];
		int numBytes = 0;
		
		while((numBytes = bis.read(b)) != -1){
			aos.write(b, 0, numBytes);
		}
		byte resultByteArray[] = aos.toByteArray();
		
		System.out.println(new String(resultByteArray));
		
		bis.close();
		aos.close();
		
		ByteArrayInputStream ais = new ByteArrayInputStream(resultByteArray);

		InputSource inputXML = new InputSource(ais);
		XPathFactory factory = XPathFactory.newInstance();
		XPath xPath = factory.newXPath();
		Node nodeStatus = (Node)xPath.evaluate("/GeocodeResponse//status", inputXML, XPathConstants.NODE);
		Element elementStatus = (Element)nodeStatus;
		String statusStr = elementStatus.getTextContent();
		if("REQUEST_DENIED".equals(statusStr)){
			throw new MyNeighborException("Request Denied (" + urlStr + ")");
		}
		else if("OVER_QUERY_LIMIT".equals(statusStr)){
			throw new MyNeighborException("Over Query Limit (" + urlStr + ")");
		}
		ais.close();
		
		ais = new ByteArrayInputStream(resultByteArray);

		inputXML = new InputSource(ais);
		Node node = (Node)xPath.evaluate("/GeocodeResponse//location", inputXML, XPathConstants.NODE);
		if(node == null){
			throw new MyNeighborException("Location not found (status: " + statusStr + ", url: " + urlStr + ")");
		}
		NodeList nodeList = node.getChildNodes();
		String latStr = null;
		String lonStr = null;
		for(int i = 0; i < nodeList.getLength(); i++)
		{
			Node n = nodeList.item(i);
			if(n.getNodeType() == Node.ELEMENT_NODE)
			{
				Element e = (Element)n;
				if("lat".equals(e.getNodeName())){
					latStr = e.getTextContent();
					System.out.println(latStr);
				}
				else if("lng".equals(e.getNodeName())){
					lonStr = e.getTextContent();
					System.out.println(lonStr);
				}
			}
		}
		ais.close();
		double latFloat = Double.valueOf(latStr);
		double lonFloat = Double.valueOf(lonStr);

		result[0] = latFloat;
		result[1] = lonFloat;
		return result;
	}
}
